package com.tyqx.hashchainbiz.service.impl;

// import com.alibaba.fastjson.JSON;
import com.tyqx.hashchainbean.module.HashIndex;
import com.tyqx.hashchainbean.module.JZTGS1Relationship;
import com.tyqx.hashchainbean.module.JZTLogistics;
import com.tyqx.hashchainbean.module.NoHashValueJson;
import com.tyqx.hashchainbean.vo.JZTGS1RelationshipVO;
import com.tyqx.hashchainbean.vo.JZTLogisticsAndGS1VO;
import com.tyqx.hashchainbean.vo.JZTLogisticsDataVO;
import com.tyqx.hashchainbean.vo.JZTLogisticsVO;
import com.tyqx.hashchainbiz.service.JZTLogisticsService;
import com.tyqx.hashchaindao.mapper.HashIndexMapper;
import com.tyqx.hashchaindao.mapper.JZTGS1RelationshipMapper;
import com.tyqx.hashchaindao.mapper.JZTLogisticsMapper;
import com.tyqx.hashchaindao.mapper.NoHashValueJsonMapper;
import com.tyqx.hashchainutil.common.HashValueUtil;
import hashchainutil.common.EmptyUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;

@Service("jztLogisticsService")
public class JZTLogisticsServiceImpl implements JZTLogisticsService {

    @Resource
    private JZTLogisticsMapper jztLogisticsMapper;

    @Resource
    private HashIndexMapper hashIndexMapper;

    @Resource
    private NoHashValueJsonMapper noHashValueJsonMapper;

    @Resource
    private JZTGS1RelationshipMapper jztgs1RelationshipMapper;

    @Async
    @Override
    public Future<String> addJZTLogistics(JZTLogistics jztLogistics) throws Exception {
        /*Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date createTime = sdf.parse(sdf.format(currentDate));
        jztLogistics.setCreateTime(createTime);
        jztLogistics.setUpdateTime(createTime);*/
        String donateCashStr = jztLogistics.toString();
        //HashIndex hashIndex=HashValueUtil.getHashValue(donateCashStr);
        HashIndex hashIndex = new HashIndex();
        int trials = 3;
        Integer insertChainFlag = 0;
        Integer flag1 = 0;
        Integer flag2 = 0;
        int sleepNum = 1000;

        for (int i = 0; i < trials; i++) {
            hashIndex = HashValueUtil.getHashValue(donateCashStr);
            String hashValue = hashIndex.getHashValue();
            String txId = hashIndex.getTxId();
            Long blockNum = hashIndex.getBlockNum();
            if (EmptyUtils.isNotEmpty(hashValue) && EmptyUtils.isNotEmpty(txId) && EmptyUtils.isNotEmpty(blockNum)) {
                insertChainFlag = 1;
                break;
            } else {
                sleepNum = sleepNum * i * 5;
                Thread.sleep(sleepNum);
            }

        }

        if (insertChainFlag > 0) {
            jztLogistics.setHashValue(hashIndex.getHashValue());
            flag1 = hashIndexMapper.insert(hashIndex);
            flag2 = jztLogisticsMapper.addJZTLogistics(jztLogistics);
            if (flag1 == 0) {
                String hashIndexStr = hashIndex.toString();
            }
            if (flag2 == 0) {
                //tianjia database
                String donateCashStr1 = jztLogistics.toString();
            }
        }

        if (insertChainFlag == 0) {
            //tianjia database
            NoHashValueJson noHashValueJson = new NoHashValueJson();
            noHashValueJson.setRecordJson(donateCashStr);
            noHashValueJson.setHashTableName("jzt_logistics");
            noHashValueJsonMapper.insert(noHashValueJson);
        }
        return new AsyncResult<String>("添加成功");

    }


    @Async
    @Override
    public Future<String> batchAddJZTLogistics(List<JZTLogistics> jztLogisticsList) throws Exception {
        int size = jztLogisticsList.size();
        for (int k = 0; k < size; k++) {
            JZTLogistics jztLogistics = jztLogisticsList.get(k);

            String jztLogisticsStr = jztLogistics.toString();
            HashIndex hashIndex = new HashIndex();
            Integer insertChainFlag = 0;
            String hashValue = "";

            // data to blockchain
            hashIndex = HashValueUtil.getHashValue(jztLogisticsStr);
            hashValue = hashIndex.getHashValue();
            String txId = hashIndex.getTxId();
            Long blockNum = hashIndex.getBlockNum();
            if (EmptyUtils.isNotEmpty(hashValue) && EmptyUtils.isNotEmpty(txId) && EmptyUtils.isNotEmpty(blockNum)) {
                insertChainFlag = 1;
                noHashValueJsonMapper.updateStatus(1, hashIndex);
            }


            if (insertChainFlag > 0) {
                jztLogistics.setHashValue(hashIndex.getHashValue());
                recordJZTLogistics(hashValue, hashIndex, jztLogistics);
            }
        }
        return new AsyncResult<String>("添加成功");

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer recordJZTLogistics(String hashValue, HashIndex hashIndex, JZTLogistics jztLogistics) throws Exception {
        Integer flag1 = hashIndexMapper.insert(hashIndex);
        Integer flag2 = jztLogisticsMapper.addJZTLogistics(jztLogistics);
        Integer flag3 = noHashValueJsonMapper.deleteByHashValue(hashValue);
        if (flag1 == 0 || flag2 == 0 || flag3 == 0){
            throw new Exception("record error");
        }
        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer recordJZTLogisticsBatch(List<String> hashValueList, List<HashIndex> hashIndexList, List<JZTLogistics> jztLogisticsList) throws Exception {
        Integer flag1 = hashIndexMapper.insertBatch(hashIndexList);
        Integer flag2 = jztLogisticsMapper.insertBatch(jztLogisticsList);
        Integer flag3 = noHashValueJsonMapper.deleteBatchByHashValue(hashValueList);
        if (flag1 == 0 || flag2 == 0 || flag3 == 0){
            throw new Exception("record error");
        }
        return 1;
    }


    @Override
    public List<JZTLogisticsDataVO> selectAll() {
        return jztLogisticsMapper.selectAll();
    }

    @Override
    public Integer insertBatch(List<JZTLogistics> jztLogisticsList) {
        return jztLogisticsMapper.insertBatch(jztLogisticsList);
    }

    @Override
    public List<JZTLogisticsVO> getJZTLogisticsByTraceabilityCode(List<String> traceabilityCodes) {
        return jztLogisticsMapper.getJZTLogisticsByTraceabilityCode(traceabilityCodes);
    }

    @Override
    public List<JZTLogisticsAndGS1VO> getJZTLogisticsAndGS1ByTraceabilityCode(List<String> traceabilityCodes) {
        List<JZTLogisticsAndGS1VO> jztLogisticsAndGS1VOList=jztLogisticsMapper.getJZTLogisticsAndGS1ByTraceabilityCode(traceabilityCodes);
        for (int i=0;i<jztLogisticsAndGS1VOList.size();i++){
            JZTLogisticsAndGS1VO jztLogisticsAndGS1VO=jztLogisticsAndGS1VOList.get(i);
            String traceabilityCode=jztLogisticsAndGS1VO.getTraceabilityCode();
            List<JZTGS1RelationshipVO> jztgs1RelationshipVOList=jztgs1RelationshipMapper.getJZTGS1RelationshipListByTraceabilityCode(traceabilityCode);
            String ssccCode="";
            if(jztgs1RelationshipVOList.size()>0){
                JZTGS1RelationshipVO jztgs1RelationshipVO=jztgs1RelationshipVOList.get(0);
                ssccCode=jztgs1RelationshipVO.getSsccCode();
            }
            jztLogisticsAndGS1VO.setSsccCode(ssccCode);

        }
        return jztLogisticsAndGS1VOList;
    }

    @Override
    public List<JZTLogisticsVO> grantGetJZTLogisticsByTraceabilityCode(List<String> traceabilityCodes, String userName) {
        return jztLogisticsMapper.grantGetJZTLogisticsByTraceabilityCode(traceabilityCodes, userName);
    }

    @Override
    public List<JZTLogisticsAndGS1VO> grantGetJZTLogisticsAndGS1ByTraceabilityCode(List<String> traceabilityCodes, String userName) {
        List<JZTLogisticsAndGS1VO> jztLogisticsAndGS1VOList=jztLogisticsMapper.grantGetJZTLogisticsAndGS1ByTraceabilityCode(traceabilityCodes,userName);
        for (int i=0;i<jztLogisticsAndGS1VOList.size();i++){
            JZTLogisticsAndGS1VO jztLogisticsAndGS1VO=jztLogisticsAndGS1VOList.get(i);
            String traceabilityCode=jztLogisticsAndGS1VO.getTraceabilityCode();
            List<JZTGS1RelationshipVO> jztgs1RelationshipVOList=jztgs1RelationshipMapper.getJZTGS1RelationshipListByTraceabilityCode(traceabilityCode);
            String ssccCode="";
            if(jztgs1RelationshipVOList.size()>0){
                JZTGS1RelationshipVO jztgs1RelationshipVO=jztgs1RelationshipVOList.get(0);
                ssccCode=jztgs1RelationshipVO.getSsccCode();
            }
            jztLogisticsAndGS1VO.setSsccCode(ssccCode);

        }
        return jztLogisticsAndGS1VOList;
    }

    @Override
    public List<JZTLogisticsVO> getJZTLogisticsByCode(String traceabilityCode) {
        return jztLogisticsMapper.getJZTLogisticsByCode(traceabilityCode);
    }


}
